// ThreadPool.h - 线程池实现
// 基于Muduo设计哲学，提供高效、灵活的线程池功能

#ifndef MODERN_THREAD_POOL_H
#define MODERN_THREAD_POOL_H

#include <functional>
#include <memory>
#include <string>
#include <vector>
#include <queue>
#include <atomic>
#include <mutex>
#include <condition_variable>
#include <future>
#include <type_traits>
#include <utility>

#include "Thread.h"

namespace cytoolkit {

// 前向声明
class ThreadPoolImpl;

// 线程池配置选项
struct ThreadPoolOptions {
    // 线程池名称
    std::string name = "ThreadPool";
    
    // 初始线程数
    size_t initialThreads = 4;
    
    // 最大线程数（0表示无限制）
    size_t maxThreads = 0;
    
    // 队列最大任务数（0表示无限制）
    size_t maxQueueSize = 0;
    
    // 是否允许核心线程超时退出
    bool allowCoreThreadTimeout = false;
    
    // 线程空闲超时时间（毫秒）
    int64_t keepAliveTimeMs = 60000; // 默认1分钟
};

// 线程池状态枚举
enum class ThreadPoolState {
    kRunning,   // 运行中
    kShuttingDown, // 正在关闭
    kTerminated // 已终止
};

// 线程池类
class ThreadPool {
public:
    // 构造函数
    explicit ThreadPool(const ThreadPoolOptions& options = ThreadPoolOptions());
    
    // 带参构造函数，简化版
    ThreadPool(size_t numThreads, const std::string& name = "ThreadPool");
    
    // 析构函数
    ~ThreadPool();
    
    // 禁止拷贝
    ThreadPool(const ThreadPool&) = delete;
    ThreadPool& operator=(const ThreadPool&) = delete;
    
    // 禁止移动
    ThreadPool(ThreadPool&&) = delete;
    ThreadPool& operator=(ThreadPool&&) = delete;
    
    // 启动线程池
    void start();
    
    // 关闭线程池，等待所有任务完成
    void shutdown();
    
    // 立即关闭线程池，丢弃所有未执行的任务
    void shutdownNow();
    
    // 等待所有任务完成
    void waitForTasks();
    
    // 提交任务，返回future
    template<typename F, typename... Args>
    auto submit(F&& f, Args&&... args) -> std::future<typename std::result_of<F(Args...)>::type>;
    
    // 提交不关心返回值的任务
    template<typename F, typename... Args>
    void execute(F&& f, Args&&... args);
    
    // 调整线程池大小
    bool resize(size_t numThreads);
    
    // 获取当前线程数
    size_t threadCount() const;
    
    // 获取活跃线程数
    size_t activeThreadCount() const;
    
    // 获取队列中的任务数
    size_t queueSize() const;
    
    // 获取线程池状态
    ThreadPoolState state() const;
    
    // 获取线程池名称
    const std::string& name() const;
    
    // 设置线程名称前缀
    void setThreadNamePrefix(const std::string& prefix);
    
    // 清空任务队列
    void clearTasks();
    
    // 检查线程池是否已满
    bool isFull() const;
    
    // 检查线程池是否为空（没有任务）
    bool isEmpty() const;

private:
    // 线程池实现的内部类指针
    std::unique_ptr<ThreadPoolImpl> impl_;
};

// 线程池实现类
class ThreadPoolImpl {
public:
    // 构造函数
    explicit ThreadPoolImpl(const ThreadPoolOptions& options);
    
    // 析构函数
    ~ThreadPoolImpl();
    
    // 禁止拷贝
    ThreadPoolImpl(const ThreadPoolImpl&) = delete;
    ThreadPoolImpl& operator=(const ThreadPoolImpl&) = delete;
    
    // 禁止移动
    ThreadPoolImpl(ThreadPoolImpl&&) = delete;
    ThreadPoolImpl& operator=(ThreadPoolImpl&&) = delete;
    
    // 启动线程池
    void start();
    
    // 关闭线程池
    void shutdown(bool waitForTasks = true);
    
    // 等待所有任务完成
    void waitForTasks();
    
    // 提交任务到队列
    template<typename Func>
    auto submit(Func&& func) -> std::future<typename std::result_of<Func()>::type>;
    
    // 执行不关心返回值的任务
    template<typename Func>
    void execute(Func&& func);
    
    // 调整线程池大小
    bool resize(size_t numThreads);
    
    // 工作线程函数
    void workerThreadFunc();
    
    // 获取当前线程数
    size_t threadCount() const;
    
    // 获取活跃线程数
    size_t activeThreadCount() const;
    
    // 获取队列中的任务数
    size_t queueSize() const;
    
    // 获取线程池状态
    ThreadPoolState state() const;
    
    // 获取线程池名称
    const std::string& name() const;
    
    // 设置线程名称前缀
    void setThreadNamePrefix(const std::string& prefix);
    
    // 清空任务队列
    void clearTasks();
    
    // 检查线程池是否已满
    bool isFull() const;
    
    // 检查线程池是否为空（没有任务）
    bool isEmpty() const;

private:
    // 线程池配置
    ThreadPoolOptions options_;
    
    // 线程池名称
    std::string name_;
    
    // 线程池状态
    std::atomic<ThreadPoolState> state_;
    
    // 工作线程列表
    std::vector<std::unique_ptr<Thread>> workers_;
    
    // 任务队列
    std::queue<std::function<void()>> tasks_;
    
    // 线程安全相关
    mutable std::mutex mutex_;
    std::condition_variable notEmpty_;    // 任务队列非空条件
    std::condition_variable notFull_;     // 任务队列非满条件
    std::condition_variable taskDone_;    // 任务完成条件
    
    // 活跃线程计数
    std::atomic<size_t> activeThreads_;
    
    // 线程名称前缀
    std::string threadNamePrefix_;
};

// ThreadPool模板方法实现
template<typename F, typename... Args>
auto ThreadPool::submit(F&& f, Args&&... args) -> std::future<typename std::result_of<F(Args...)>::type> {
    return impl_->submit(std::bind(std::forward<F>(f), std::forward<Args>(args)...));
}

template<typename F, typename... Args>
void ThreadPool::execute(F&& f, Args&&... args) {
    impl_->execute(std::bind(std::forward<F>(f), std::forward<Args>(args)...));
}

// ThreadPoolImpl模板方法实现
template<typename Func>
auto ThreadPoolImpl::submit(Func&& func) -> std::future<typename std::result_of<Func()>::type> {
    using ReturnType = typename std::result_of<Func()>::type;
    
    auto task = std::make_shared<std::packaged_task<ReturnType()>>(std::forward<Func>(func));
    std::future<ReturnType> result = task->get_future();
    
    {  
        std::unique_lock<std::mutex> lock(mutex_);
        
        // 检查线程池状态
        if (state_ != ThreadPoolState::kRunning) {
            throw std::runtime_error("submit on stopped ThreadPool");
        }
        
        // 检查队列是否已满
        if (options_.maxQueueSize > 0 && tasks_.size() >= options_.maxQueueSize) {
            // 等待队列不满
            notFull_.wait(lock, [this]() {
                return tasks_.size() < options_.maxQueueSize || 
                       state_ != ThreadPoolState::kRunning;
            });
            
            // 再次检查状态
            if (state_ != ThreadPoolState::kRunning) {
                throw std::runtime_error("submit on stopped ThreadPool");
            }
        }
        
        // 将任务包装成无参函数并添加到队列
        tasks_.emplace([task]() {
            (*task)();
        });
    }
    
    // 通知一个等待中的线程有新任务
    notEmpty_.notify_one();
    
    return result;
}

template<typename Func>
void ThreadPoolImpl::execute(Func&& func) {
    {  
        std::unique_lock<std::mutex> lock(mutex_);
        
        // 检查线程池状态
        if (state_ != ThreadPoolState::kRunning) {
            throw std::runtime_error("execute on stopped ThreadPool");
        }
        
        // 检查队列是否已满
        if (options_.maxQueueSize > 0 && tasks_.size() >= options_.maxQueueSize) {
            // 等待队列不满
            notFull_.wait(lock, [this]() {
                return tasks_.size() < options_.maxQueueSize || 
                       state_ != ThreadPoolState::kRunning;
            });
            
            // 再次检查状态
            if (state_ != ThreadPoolState::kRunning) {
                throw std::runtime_error("execute on stopped ThreadPool");
            }
        }
        
        // 添加任务到队列
        tasks_.emplace(std::forward<Func>(func));
    }
    
    // 通知一个等待中的线程有新任务
    notEmpty_.notify_one();
}

} // namespace cytoolkit

#endif // MODERN_THREAD_POOL_H